﻿using AutoUpdater;
using AutoUpdater.Bll;
using AutoUpdater.Entity;
using AutoUpdater.Util;
using System;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Windows.Forms;

namespace UcAutoUpdate
{
    public partial class FrmCheckVsc : Form
    {
        private string systemCode = "360"; //主程序目录
        private string title;
        private string callBackExeName;

        public string StationCode = string.Empty;
        public string userCode = string.Empty;

        public SysBasicInfo SysBasic;
        private Thread thread;

        public FrmCheckVsc()
        {
            InitializeComponent();

            title = SystemXmlUtil.GetTitle();
            callBackExeName = SystemXmlUtil.GetCallbackExeName();

            //this.FormClosing += FrmCheck_FormClosing;
        }

        public bool ChecckNeedUpdate(out string error)
        {
            error = string.Empty;

            FileRequestVo vo = new FileRequestVo();
            vo.sysCode = systemCode;
            vo.sysVersion = SystemXmlUtil.GetClientVersion();
            vo.fileVersion = SystemXmlUtil.GetSysFileMaxVersion();
            vo.stationCode = StationCode;
            vo.userCode = userCode;

            var sysResult = FileCheckBll.CheckBaseSys(vo);

            if(sysResult.code != 200)
            {
                error = sysResult.message;
                return false;
            }

            SysBasic = sysResult.data;

            if (SysBasic.sysFileMaxVs.CompareTo(vo.fileVersion)>0)
            {
                return true;
            }
            return false;
        }

        private void FrmCheck_Shown(object sender, EventArgs e)
        {
            KillMainExe();

            if (ProcessUtil.StartExePath.Equals(ProcessUtil.TempPath))
            {
                string copyerror;
                if (CopyDirectory(Environment.CurrentDirectory, ProcessUtil.BaseDirectory, out copyerror))
                {
                    RunMainExe();
                }
                else
                {
                    ShowMessage("文件复制出错:" + copyerror);
                    MessageBox.Show("文件复制出错:"+ copyerror);
                    RunMainExe();
                }
                
                return;
            }

            string error;
            bool needUpdate = ChecckNeedUpdate(out error);
            if (!string.IsNullOrEmpty(error))
            {
                MessageBox.Show(error);
                RunMainExe();
                return ;
            }
            else if (!needUpdate)
            {
                RunMainExe();
                return;
            }

            thread = new Thread(DealUpdate);
            thread.Start();
        }

        private void ShowMessage(string message)
        {
            this.Invoke(new Action(() =>
            {
                try
                {
                    richTextBox1.AppendText(message);
                    richTextBox1.AppendText(Environment.NewLine);
                }
                catch (Exception) { }
            }));
        }
        

        /// <summary>
        /// 文件夹下所有内容copy
        /// </summary>
        /// <param name="SourcePath">要Copy的文件夹</param>
        /// <param name="DestinationPath">要复制到哪个地方</param>
        /// <param name="overwriteexisting">是否覆盖</param>
        /// <returns></returns>
        private static bool CopyDirectory(string SourcePath, string DestinationPath, out string error,bool overwriteexisting = true)
        {
            error = string.Empty;
            bool ret = false;
            try
            {
                SourcePath = SourcePath.EndsWith(@"\") ? SourcePath : SourcePath + @"\";
                DestinationPath = DestinationPath.EndsWith(@"\") ? DestinationPath : DestinationPath + @"\";

                if (Directory.Exists(SourcePath))
                {
                    if (Directory.Exists(DestinationPath) == false)
                        Directory.CreateDirectory(DestinationPath);

                    foreach (string fls in Directory.GetFiles(SourcePath))
                    {
                        FileInfo flinfo = new FileInfo(fls);
                        flinfo.CopyTo(DestinationPath + flinfo.Name, overwriteexisting);
                    }
                    foreach (string drs in Directory.GetDirectories(SourcePath))
                    {
                        DirectoryInfo drinfo = new DirectoryInfo(drs);
                        string errormssage;
                        if (CopyDirectory(drs, DestinationPath + drinfo.Name,out errormssage, overwriteexisting) == false)
                        {
                            ret = false;
                            error = errormssage;
                            return ret;
                        }   
                    }
                }
                ret = true;
            }
            catch (Exception ex)
            {
                error = ex.ToString();
                ret = false;
            }
            return ret;
        }

        private void DealUpdate()
        {
            try
            {
                string tempPath = ProcessUtil.TempPath;

                FileRequestVo vo = new FileRequestVo();
                vo.sysCode = systemCode;
                vo.sysVersion = SysBasic.versionNo;
                vo.fileVersion = SystemXmlUtil.GetSysFileMaxVersion();
                vo.stationCode = StationCode;
                vo.userCode = userCode;

                //如果版本回退，需要重新下载所有的文件
                if(vo.sysVersion.CompareTo(SystemXmlUtil.GetClientVersion()) < 0)
                {
                    vo.fileVersion = "";
                }

                var getFileReuslt = FileCheckBll.GetAllNeedUpdateFile(vo);
                if (getFileReuslt.code != 200)
                {
                    string message = "系统更新异常，下载文件出错" + getFileReuslt.message;
                    ShowMessage(message);
                    MessageBox.Show(message);
                    Application.Exit();
                }

                var fileMessageList = getFileReuslt.data;

                this.Invoke(new Action(() =>
                {
                    try
                    {
                        progressBar1.Maximum = fileMessageList.Count;
                        progressBar1.Step = 1;
                        progressBar1.Value = 0;
                    }
                    catch (Exception) { }
                }));
                


                if (fileMessageList == null && fileMessageList.Count == 0)
                {
                    RunMainExe();
                }

                bool modifyUpdateExe = false;
                foreach (var fileTemp in fileMessageList)
                {
                    ShowMessage("正在下载"+ fileTemp.filePath);
                    if ("upateExe.exe".Equals(fileTemp.fileName))
                    {
                        modifyUpdateExe = true;
                    }

                    string filePath = Path.Combine(tempPath, fileTemp.filePath);
                    //string filename = Path.Combine(filePath, fileTemp.fileName);

                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }

                    FileRequestVo downloadVo = new FileRequestVo();
                    downloadVo.fileName = fileTemp.fileName;
                    downloadVo.filePath = fileTemp.fileUrl;
                    downloadVo.position = 0;

                    // 写入文件
                    using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate))
                    {
                        while (downloadVo.position < fileTemp.fileLength)
                        {
                            byte[] fileByte = FileCheckBll.DownLoadFile(downloadVo);

                            if(fileByte == null || fileByte.Length ==0)
                            {
                                break;
                            }
                            fileStream.Seek(downloadVo.position, SeekOrigin.Begin);
                            fileStream.Write(fileByte, 0, fileByte.Length);

                            downloadVo.position += fileByte.Length;
                        }
                        
                    }

                    this.Invoke(new Action(() =>
                    {
                        try
                        {
                            progressBar1.PerformStep();
                        }
                        catch (Exception) { }
                    }));
                }

                if (modifyUpdateExe)
                {
                    RunUpdateTempAndExit();
                    return;
                }

                ShowMessage("正在复制文件");
                string copyerror;
                if (CopyDirectory(tempPath, ProcessUtil.BaseDirectory, out copyerror))
                {
                    Directory.Delete(tempPath,true);
                    SystemXmlUtil.SetClientVersion(SysBasic.versionNo);
                    SystemXmlUtil.SetSysFileMaxVersion(SysBasic.sysFileMaxVs);
                    RunMainExe();
                    return;
                }

                MessageBox.Show("系统更新异常，无法复制文件"+ copyerror);
                Application.Exit();
            }
            catch (Exception ex)
            {
                string message = "更新异常" + ex.ToString();
                ShowMessage(message);
                MessageBox.Show(message);
                return;
            }
        }

        private void KillUpdateExe()
        {
            //string processName = this.callBackExeName.Substring(0, this.callBackExeName.Length - 4);
            //ESBasic.Helpers.ApplicationHelper.ReleaseAppInstance(processName);
        }

        private void KillMainExe()
        {
            string processName = this.callBackExeName.Substring(0, this.callBackExeName.Length - 4);
            ESBasic.Helpers.ApplicationHelper.ReleaseAppInstance(processName);
        }

        private void RunUpdateTempAndExit()
        {
            string filename = Path.Combine(System.Windows.Forms.Application.StartupPath, "tempUpdate", "update.exe");
            if (File.Exists(filename))
            {
                System.Diagnostics.Process myProcess = System.Diagnostics.Process.Start(filename);
            }
            Application.Exit();
        }

        private void RunMainExe()
        {
            string filename = Path.Combine(ProcessUtil.BaseDirectory, this.callBackExeName);
            if (File.Exists(filename))
            {
                System.Diagnostics.Process myProcess = System.Diagnostics.Process.Start(filename);
            }
            Application.Exit();
        }

        /// <summary>
        /// 随机建立一个文件夹用来存在从服务器下载的新版本
        /// </summary>
        /// <returns></returns>
        private string CreateUpdateDir()
        {
            var currentPath = System.Windows.Forms.Application.StartupPath;

            string tempDir = Guid.NewGuid().ToString().Replace("-", "");

            var currentPathDir = new System.IO.DirectoryInfo(currentPath + "\\" + tempDir);

            if (currentPathDir.Exists)
            {
                currentPathDir.Delete(true);
            }
            else
            {
                currentPathDir.Create();
            }

            return currentPathDir.FullName;
        }
    }
}
